package com.txw.travel.aop;

import com.txw.travel.bean.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Component //托管
@Aspect //定义切面
public class LogAop {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private final static Logger logger = LoggerFactory.getLogger(LogAop.class);

    private Log initLog() {
        Log log = new Log();

        Date visitTime = (Date) request.getAttribute("visitTime"); // 访问时间
        Date now = new Date();
        int executionTime = (int) (now.getTime() - visitTime.getTime()); // 访问时长
        String ip = request.getRemoteAddr(); // 访问ip
        String url = request.getRequestURI();// 访问路径
        // 拿到security中的User对象
        Object user = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user instanceof User) {
            String username = ((User) user).getUsername();
            log.setUsername(username);
        }

        log.setExecutionTime(executionTime);
        log.setUrl(url);
        log.setIp(ip);
        log.setVisitTime(visitTime);

        return log;
    }

    @Pointcut("execution(* com.txw.travel.controller.backstage.*.*(..))")
    public void pointCut() {
    }

    @Before("pointCut()") //定义通知
    public void doBefore() {
        //记录请求时间放入请求中
        Date date = new Date();
        request.setAttribute("visitTime", date);
    }

    @After("pointCut()") //定义通知
    public void doAfter() {
        Log log = initLog();
        logger.info(log.toString());
    }

    @AfterThrowing(pointcut = "pointCut()",throwing = "ex")
    public void doAfterThrowing(Throwable ex) {
        Log log = initLog();

        // 异常信息
        String exMessage = ex.getMessage();
        log.setExceptionMessage(exMessage);

        logger.info(log.toString());
    }
}
